include('mimeparse.js');
include('base.js');
var json = require('json.js');

var tests = {
    test_parseMediaRange : function() {
        T(eq(["application", "xml", {"q" : "1"}],
            parseMediaRange("application/xml;q=1")));

        T(eq(["application", "xml", {"q" : "1"}],
            parseMediaRange("application/xml")));

        T(eq(["application", "xml", {"q" : "1"}],
            parseMediaRange("application/xml;q=")));

        T(eq(["application", "xml", {"q" : "1"}],
            parseMediaRange("application/xml ; q=")));

        T(eq(["application", "xml", {"q" : "1", "b" : "other"}],
            parseMediaRange("application/xml ; q=1;b=other")));

        T(eq(["application", "xml", {"q" : "1", "b" : "other"}],
            parseMediaRange("application/xml ; q=2;b=other")));

        // Java URLConnection class sends an Accept header that includes a single "*"
        T(eq(["*", "*", {"q" : ".2"}],
            parseMediaRange(" *; q=.2")));
    },
    test_rfc_2616_example : function() {
        var accept = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5";

        T(eq(1, quality("text/html;level=1", accept)));
        T(eq(0.7, quality("text/html", accept)));
        T(eq(0.3, quality("text/plain", accept)));
        T(eq(0.5, quality("image/jpeg", accept)));
        T(eq(0.4, quality("text/html;level=2", accept)));
        T(eq(0.7, quality("text/html;level=3", accept)));
    },
    test_bestMatch : function() {
        var mimeTypesSupported = ['application/xbel+xml', 'application/xml'];
        // direct match
        T(eq(bestMatch(mimeTypesSupported, 'application/xbel+xml'), 'application/xbel+xml'));
        // direct match with a q parameter
        T(eq(bestMatch(mimeTypesSupported, 'application/xbel+xml; q=1'), 'application/xbel+xml'));

        // direct match of our second choice with a q parameter
        T(eq(bestMatch(mimeTypesSupported, 'application/xml; q=1'), 'application/xml'));
        // match using a subtype wildcard
        T(eq(bestMatch(mimeTypesSupported, 'application/*; q=1'), 'application/xml'));
        // match using a type wildcard
        T(eq(bestMatch(mimeTypesSupported, '*/*'), 'application/xml'));

        mimeTypesSupported = ['application/xbel+xml', 'text/xml']
        // match using a type versus a lower weighted subtype
        T(eq(bestMatch(mimeTypesSupported, 'text/*;q=0.5,*/*; q=0.1'), 'text/xml'));
        // fail to match anything
        T(eq(bestMatch(mimeTypesSupported, 'text/html,application/atom+xml; q=0.9'), ''));

        // common AJAX scenario
        mimeTypesSupported = ['application/json', 'text/html']
        T(eq(bestMatch(mimeTypesSupported, 'application/json, text/javascript, */*'), 'application/json'));
        // verify fitness ordering
        T(eq(bestMatch(mimeTypesSupported, 'application/json, text/html;q=0.9'), 'application/json'));

    },
    test_support_wildcards : function() {
        var mime_types_supported = ['image/*', 'application/xml']
        // match using a type wildcard
        T(eq(bestMatch(mime_types_supported, 'image/png'), 'image/*'));
        // match using a wildcard for both requested and supported
        T(eq(bestMatch(mime_types_supported, 'image/*'), 'image/*'));

    }
};

// from CouchDB's Test Runner (Apache 2.0 license)
function patchTest(fun) {
    var source = fun.toString();
    var output = "";
    var i = 0;
    var testMarker = "T("
    while (i < source.length) {
        var testStart = source.indexOf(testMarker, i);
        if (testStart == -1) {
            output = output + source.substring(i, source.length);
            break;
        }
        var testEnd = source.indexOf(");", testStart);
        var testCode = source.substring(testStart + testMarker.length, testEnd);
        output += source.substring(i, testStart) + "T(" + testCode + "," + json.encode(testCode);
        i = testEnd;
    }
    try {
        return eval("(" + output + ")");
    } catch (e) {
        return null;
    }
}

function T(arg1, arg2) {
    var message = (arg2 != null ? unescape(arg2) : arg1).toString();
    if (arg1) {
        log(message, 'pass');
    } else {
        // log(arg2)
        log(message, 'fail');
    }
}

info("Starting " + moduleUrl + " tests.");
for (test in tests) {
    log("Running "+test);
    var testFun = tests[test];
    try {
        testFun = patchTest(testFun) || testFun;
        testFun();
    } catch (e) {
        error(''+e);
    }
}
info("Finished " + moduleUrl + " tests.");

